

// macro_rules

/*
Rust provides a powerful macro system that allows metaprogramming. As you've seen in previous chapters, macros look like functions, except that their name ends with a bang !, but instead of generating a function call, macros are expanded into source code that gets compiled with the rest of the program. However, unlike macros in C and other languages, Rust macros are expanded into abstract syntax trees, rather than string preprocessing, so you don't get unexpected precedence bugs.
Rust提供了一个强大的宏系统，允许元编程。正如您在前几章中看到的，宏看起来像函数，只是它们的名字以“砰!”结尾，但是宏不是生成函数调用，而是扩展为源代码，并与程序的其他部分一起编译。但是，与C语言和其他语言中的宏不同，Rust宏被扩展为抽象语法树，而不是字符串预处理，因此不会出现意外的优先级错误。
*/

// This is a simple macro named `say_hello`.
macro_rules! say_hello {
    // `()` indicates that the macro takes no argument.
    () => (
        // The macro will expand into the contents of this block.
        println!("Hello!");
    )
}

pub fn test_fn() {
    // This call will expand into `println!("Hello");`
    say_hello!()
}
/*
So why are macros useful?

    Don't repeat yourself. There are many cases where you may need similar functionality in multiple places but with different types. Often, writing a macro is a useful way to avoid repeating code. (More on this later)

    Domain-specific languages. Macros allow you to define special syntax for a specific purpose. (More on this later)

    Variadic interfaces. Sometime you want to define an interface that takes a variable number of arguments. An example is println! which could take any number of arguments, depending on the format string!. (More on this later)
那么宏为什么有用呢?
不要重复你自己。在许多情况下，您可能需要在多个位置使用相同的功能，但类型不同。通常，编写宏是避免重复代码的有效方法。(稍后会详细介绍)
领域特定语言。宏允许您为特定目的定义特殊语法。(稍后会详细介绍)
可变的接口。有时，您希望定义一个具有可变数量参数的接口。一个例子就是println!它可以接受任意数量的参数，这取决于格式字符串!(稍后会详细介绍)
*/